<template>
  <div>
    <div v-if="!mini" class="query-container">
      <span class="query-item">
        地图
        <el-select v-model="query.mapId" style="width: 200px;" @change="changeMap">
          <el-option v-for="item in selectMapList" :key="item.id" :label="item.name" :value="item.id" />
        </el-select>
      </span>
    </div>
    <div id="map" ref="map" :style="mini ? 'height: 85vh;' : ''" style="background-color:blue">
      <div id="tips" class="ol-tips">
        <!-- <div id="tips-content" class="width:100%;height:100%;"> -->
        <div v-if="loading === true" class="pswp__preloader__icn">
          <div class="pswp__preloader__cut">
            <div class="pswp__preloader__donut" />
          </div>
        </div>

      </div>
    </div>

  </div>
</template>

<script>
import crudBasicMap from '@/api/basicMap'
import { mapGetters } from 'vuex'
import Map from 'ol/Map.js'
import Feature from 'ol/Feature'
import Polygon from 'ol/geom/Polygon'
import Stroke from 'ol/style/Stroke'
import Circle from 'ol/style/Circle'
import { Vector as SourceVec } from 'ol/source'
import { Point } from 'ol/geom'
import { Style, Icon, Fill, Text } from 'ol/style'
import { Vector as LayerVec } from 'ol/layer'
import 'ol/ol.css'
import ImageLayer from 'ol/layer/Image'
import ImageStatic from 'ol/source/ImageStatic'
import Projection from 'ol/proj/Projection'
import View from 'ol/View.js'

export default {
  name: 'RealIndex',
  components: {

  },
  props: {
    mini: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      selectMapList: [],
      selectMap: {
        mapImagePath: '',
        mapName: '',
        mapId: 0,
        width: 600,
        height: 800,
        // 缩放倍数
        proportion: 1
      },
      map: null,
      client: null,
      loading: false,
      query: {
        mapId: null,
        deptId: null,
        jobId: null,
        name: null
      },
      deptList: [],
      deptMap: {},
      jobList: [],
      jobMap: {},
      areaList: [],
      areaMap: {},
      staffList: [],
      staffsMap: {},
      staff: {},
      realDataList: [],
      // 底图范围
      baseExtent: [],
      baseLayer: null,
      baseView: null,
      regionLayer: null,
      cameraLayer: null,
      locationLayer: null,
      staffCount: 0,
      chargeCount: 0,
      zeroDimensionCodes: [],
      statistics: {
        show: false,
        // 显示类型：dept:部门，area:区域
        showType: 'dept',
        // 列表待显示人员信息
        deptStaffList: [],
        areaStaffList: [],
        selectId: null,
        loading: false
      }
    }
  },
  computed: {
    ...mapGetters([
      'baseApi',
      'fileUploadApi'
    ])
  },
  mounted() {
    // 获取所有地图数据
    this.getMapList()
  },
  methods: {
    // 切换地图
    changeMap(mapId) {
      let num
      for (num = 0; num < this.selectMapList.length; num++) {
        if (this.selectMapList[num].id === mapId) {
          this.query.mapId = this.selectMapList[num].id
          this.selectMap.mapImagePath = this.baseApi + this.selectMapList[num].mapPath
          this.selectMap.mapName = this.selectMapList[num].name
          this.selectMap.mapId = this.selectMapList[num].id
          this.selectMap.width = '13020'
          this.selectMap.height = '5910'
          this.selectMap.proportion = '300'
          break
        }
      }
      if (num >= this.selectMapList.length) {
        this.$message.error('未找到该地图，请检查!')
        return
      }

      if (this.baseLayer != null) {
        this.map.removeLayer(this.baseLayer)
        this.baseLayer = null
        this.baseView = null
      }
      // 更新底图参数
      this.loadMapParam()
      // 重新添加底图
      this.map.addLayer(this.baseLayer)
      this.map.setView(this.baseView)
      // 初始化视图定位
      this.map.getView().fit(this.baseExtent, this.map.getSize())
      // 初始化定位实时数据图层
      this.getRealLocation()
    },
    // 初始化加载地图列表
    getMapList() {
      crudBasicMap.getAll().then(res => {
        this.selectMapList = res
        if (this.selectMapList && this.selectMapList.length > 0) {
          this.query.mapId = this.selectMapList[2].id
          this.selectMap.mapId = this.selectMapList[2].id
          this.selectMap.mapName = this.selectMapList[2].name
          this.selectMap.width = 6800
          this.selectMap.height = 2700
          this.selectMap.proportion = 300
          this.selectMap.mapImagePath = this.baseApi + this.selectMapList[2].mapUrl

          // 初始化图层底图
          this.initMap()
        } else {
          this.$message.error('请先配置地图!')
        }
      })
    },

    // 加载底图参数
    loadMapParam() {
      this.baseExtent = [0, 0, '5910', '13410']
      const projection = new Projection({
        code: 'xkcd-image',
        units: 'pixels',
        extent: this.baseExtent
      })
      this.baseLayer = new ImageLayer({
        source: new ImageStatic({
          url: this.selectMap.mapImagePath, // 这里添加静态图片的地址
          projection: projection,
          imageExtent: this.baseExtent
        })
      })
      this.baseView = new View({
        projection: projection,
        center: [this.selectMap.width / 2, this.selectMap.height / 2],
        zoom: 2,
        maxZoom: 6
      })
    },
    // 初始化图层底图
    initMap() {
      const that = this
      // 初始化加载底图参数
      that.loadMapParam()
      // 初始化Map
      that.map = new Map({
        layers: [that.baseLayer],
        target: 'map',
        view: that.baseView
      })

      // 监测鼠标悬浮事件
      that.map.on('pointermove', function(event) {
        const feature = that.map.forEachFeatureAtPixel(event.pixel, function(feature, layer) {
          return feature
        })
        if (feature) {
          if (feature.get('type') === 'region' || feature.get('type') === 'camera') {
            return
          }
          const cardId = feature.get('cardId')
          switch (feature.get('type')) {
            case 'person':
              that.getStaff(cardId)
              // 设置气泡弹框显示内容和坐标位置
              break
          }
          // 修改鼠标样式
          that.map.getTargetElement().style.cursor = 'pointer'
        } else {
          // 修改鼠标样式
          that.map.getTargetElement().style.cursor = 'auto'
        }
      })

      // 监测鼠标点击事件
      that.map.on('click', function(event) {
        const feature = that.map.forEachFeatureAtPixel(event.pixel, function(feature, layer) {
          return feature
        })
        if (feature != null) {
          switch (feature.get('type')) {
            case 'region':
              that.showAreaStatistics(feature.get('regionId'))
              break
            case 'camera':
              that.preview(feature.get('cameraData'))
              break
          }
        }
      })
    },
    // 更新图层显示
    flushLocation() {
      const features = []
      const regionZeroDimension = {}
      for (let i = 0; i < this.realDataList.length; i++) {
        let name = '未知'
        if (this.realDataList[i].staff != null) {
          if (!(this.realDataList[i].staff instanceof Object)) {
            this.realDataList[i].staff = JSON.parse(this.realDataList[i].staff)
          }
          name = this.realDataList[i].staff.name
        }
        if (this.realDataList[i].staff != null) {
          if (this.query.mapId != null && this.query.mapId !== '' && this.realDataList[i].mapId !== this.query.mapId) {
            continue
          }
          if (this.query.deptId != null && this.query.deptId !== '' && this.realDataList[i].staff.deptId !== this.query.deptId) {
            continue
          }
          if (this.query.jobId != null && this.query.jobId !== '' && this.realDataList[i].staff.jobId !== this.query.jobId) {
            continue
          }
          if (this.query.name != null && this.query.name !== '' && this.realDataList[i].staff.name.indexOf(this.query.name) === -1) {
            continue
          }
        }
        // 判断是否为0维区域
        if (this.zeroDimensionCodes.indexOf(this.realDataList[i].region) !== -1) {
          if (regionZeroDimension[this.realDataList[i].region] == null) {
            regionZeroDimension[this.realDataList[i].region] = 1
          } else {
            regionZeroDimension[this.realDataList[i].region]++
          }
          continue
        }
        const feature = new Feature({
          type: 'person', // 对象类型
          cardId: this.realDataList[i].id, // 显示对象
          geometry: new Point([this.realDataList[i].x * this.selectMap.proportion, this.realDataList[i].y * this.selectMap.proportion])
        })
        let imgPath = '/static/position.svg'
        if (this.realDataList[i].alarm === '1') {
          imgPath = '/static/position-alarm.svg'
        }
        feature.setStyle(new Style({
          image: new Icon({
            src: imgPath,
            anchor: [0.5, 0.9], // 图标定位，0.5为中间，[左右，上下]
            scale: 0.15, // 图标大小
            fill: new Fill({ color: '#FFFFFF' })
          }),
          text: new Text({
            font: 'bold 12px sans-serif',
            text: name, // 显示名称
            offsetY: 12,
            fill: new Fill({ color: this.mini ? '#c6e2ff' : '#333' })
          })
        }))
        features.push(feature)
      }
      let staffCount = features.length
      for (const item in regionZeroDimension) {
        staffCount += regionZeroDimension[item]
      }
      this.staffCount = staffCount
      // 矢量要素数据源
      const source = new SourceVec({
        features: features
      })
      this.map.removeLayer(this.locationLayer)
      this.locationLayer = new LayerVec({
        source: source
      })
      this.map.addLayer(this.locationLayer)
      // 添加0维区域人数图层
      const regionFeatures = []
      for (const field in regionZeroDimension) {
        const region = this.findAreaByCode(field)
        const path = region.path
        if (path == null) {
          return
        }
        const gisArr = path.split(';')
        for (let i = 0; i < gisArr.length; i++) {
          gisArr[i] = gisArr[i].split(',')
        }
        const regionFeature = new Feature({
          geometry: new Polygon([gisArr]),
          count: regionZeroDimension[field],
          name: region.name,
          type: 'region',
          regionId: region.engineAreaId
        })
        regionFeature.setStyle(this.getStyle(regionFeature))
        regionFeatures.push(regionFeature)
      }
      if (regionFeatures.length > 0) {
        const regionSource = new SourceVec({
          features: regionFeatures
        })
        this.map.removeLayer(this.regionLayer)
        this.regionLayer = new LayerVec({
          source: regionSource
        })
        this.map.addLayer(this.regionLayer)
      }
      // 加载区域统计数据
      this.loadAreaStatistics()
      // 加载部门统计数据
      this.loadDeptStatistics()
    },
    findAreaByCode(code) {
      for (let i = 0; i < this.areaList.length; i++) {
        if (code === this.areaList[i].engineAreaId) {
          return this.areaList[i]
        }
      }
    },
    getStyle(feature) {
      return new Style({
        // 填充
        fill: new Fill({
          color: 'rgba(0,0,0, 0.2)'
        }),
        // 线
        stroke: new Stroke({
          color: '#60b4ff',
          width: 3
        }),
        // 绘制的那个标记
        image: new Circle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgb(212,35,122)'
          }),
          fill: new Fill({
            color: 'rgba(255,255,255,0.6)'
          })
        }),
        text: new Text({
          textAlign: 'center', // 位置
          textBaseline: 'middle', // 基准线
          overflow: true,
          font: 'bold 15px 宋体',
          text: feature.get('name') + ':' + feature.get('count') + '人',
          fill: new Fill({ // 文本填充样式（即文字颜色)
            color: '#c6e2ff'
          })
        })
      })
    },
    preview(camera) {
      this.$refs.preview.show(camera)
    }
  }
}
</script>

<style lang="scss" scoped>
#map {
  // position:absolute;
  /*top:100px;*/
  height: 78vh;
  bottom: 0px;
  width: 100%;
  color: #8000ff;
  z-index: 1000;
}

.ol-tips {
  width: 200PX;
  position: absolute;
  background-color: #0b85ff;
  opacity: 0.9;
  padding: 10px 10px;
  border-radius: 10px;
  border: 1px solid #cccccc;
  bottom: 12px;
  left: -50px;
  color: #ffffff;
}

.pswp__preloader__icn {
  opacity: 0.75;
  width: 24px;
  height: 24px;
  -webkit-animation: clockwise 500ms linear infinite;
  animation: clockwise 500ms linear infinite;
}

/* The idea of animating inner circle is based on Polymer loading indicator by Keanu Lee https://blog.keanulee.com/2014/10/20/the-tale-of-three-spinners.html */
.pswp__preloader__cut {
  position: relative;
  width: 12px;
  height: 24px;
  overflow: hidden;
  position: absolute;
  top: 0;
  left: 0;
}

.pswp__preloader__donut {
  box-sizing: border-box;
  width: 24px;
  height: 24px;
  border: 2px solid #000;
  border-radius: 50%;
  border-left-color: transparent;
  border-bottom-color: transparent;
  position: absolute;
  top: 0;
  left: 0;
  background: none;
  margin: 0;
  -webkit-animation: donut-rotate 1000ms cubic-bezier(.4, 0, .22, 1) infinite;
  animation: donut-rotate 1000ms cubic-bezier(.4, 0, .22, 1) infinite;
}

@-webkit-keyframes clockwise {
  0% {
    -webkit-transform: rotate(0deg)
  }
  100% {
    -webkit-transform: rotate(360deg)
  }
}

@keyframes clockwise {
  0% {
    transform: rotate(0deg)
  }
  100% {
    transform: rotate(360deg)
  }
}

@-webkit-keyframes donut-rotate {
  0% {
    -webkit-transform: rotate(0)
  }
  50% {
    -webkit-transform: rotate(-140deg)
  }
  100% {
    -webkit-transform: rotate(0)
  }
}

@keyframes donut-rotate {
  0% {
    transform: rotate(0)
  }
  50% {
    transform: rotate(-140deg)
  }
  100% {
    transform: rotate(0)
  }
}

.query-container {
  height: 50px;
  padding-top: 10px;
}

.query-item {
  width: auto;
  height: 100%;
  font-size: 15px;
  margin-left: 30px;
  float: left;
}

.reset-button {
  background-color: #ff8000;
  border: #ffddbb;
  color: #FFFFFF;
  width: 80px;
}

.data-count {
  width: 10%;
  height: 60px;
  position: absolute;
  z-index: 99;
  float: left;
}

.statistics-item {
  width: 200px;
  font-size: 30px;
  font-family: "楷体";
  font-weight: 700;
  text-align: center;
  float: left;
  line-height: 100%;
  color: slateblue;
}

.dialog {
  width: 100%;
  height: 600px;
}

.side {
  width: 30%;
  height: 100%;
  float: left;
  overflow-y: auto;
  background-color: #f9fcff;
}

.content {
  width: 65%;
  margin-left: 1%;
  height: 100%;
  float: left;
  overflow-y: auto;
}

.side-title {
  height: 25px;
  font-size: 20px;
  color: #5b5b5b;
  margin-top: 10px;
  margin-bottom: 10px;
  user-select: none;
  font-family: '宋体';
  font-weight: 600;
}

.side-line {
  width: 100%;
  height: 50px;
  font-size: 15px;
  font-family: 'Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,SimSun,sans-serif;';
  color: #898989;
  cursor: pointer;
  user-select: none;
  border-bottom: 1px solid #ddefff;
  line-height: 50px;
}

.side-line div {
  padding-left: 10px;
  height: 100%;
}

.side-line :hover {
  background-color: #e8f4ff;
}
</style>
